package com.cn.lf.wx;


import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.util.matcher.RequestMatcher;

import net.sf.json.JSONObject;


@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(HttpSecurity http) throws Exception {
	    //所有都放行
//        http.authorizeRequests()
//                .antMatchers("/**").permitAll()
//                .anyRequest().authenticated()
//                .and().csrf().disable();
//        http.cors();
        
		http.authorizeRequests().antMatchers("/api/**","/admin/**","/auth/**").permitAll().anyRequest().authenticated();
		http.headers().frameOptions().disable().cacheControl();
		http.formLogin().loginPage("/index").loginProcessingUrl("/login")
				.successHandler(new AuthenticationSuccessHandler() {
					@Override
					public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
		 					Authentication authentication) throws IOException, ServletException {
						JSONObject res = new JSONObject();
						res.put("success", true);
						res.put("msg", "登录成功");
						res.put("url", "/author/index/index");
						response.setStatus(200);
						response.setContentType("application/json;charset=UTF-8");
						response.getWriter().append(res.toString());
					}
				}).failureHandler(new AuthenticationFailureHandler() {
					@Override
					public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
							AuthenticationException exception) throws IOException, ServletException {
						JSONObject res = new JSONObject();
						res.put("success", false);
						res.put("msg", "登录失败,请检查账号密码是否正确");
						response.setStatus(200);
						response.setContentType("application/json;charset=UTF-8");
						response.getWriter().append(res.toString());
					}
				}).permitAll();
		http.logout().logoutUrl("/logout").logoutSuccessHandler(new LogoutSuccessHandler() {
			@Override
			public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
					Authentication authentication) throws IOException, ServletException {
				JSONObject res = new JSONObject();
				res.put("success", true);
				res.put("msg", "注销成功!");
				res.put("url", "/index");
				response.setStatus(200);
				response.setContentType("application/json;charset=UTF-8");
				response.getWriter().append(res.toString());
			}
		});
		
		http.exceptionHandling().defaultAuthenticationEntryPointFor(new AuthenticationEntryPoint() {
			@Override
			public void commence(HttpServletRequest request,
					HttpServletResponse response, AuthenticationException authException)
					throws IOException, ServletException {
				String requestPath = request.getServletPath();
				if(!restful(requestPath)) {
					response.setStatus(500);
			        response.setContentType("application/json;charset=UTF-8");
			        response.getWriter().append("无权访问");
				} else {
					response.setStatus(200);
			        response.setContentType("application/json;charset=UTF-8");
			        response.getWriter().append("timeout");
				}
			}
		}, new RequestMatcher() {
			@Override
			public boolean matches(HttpServletRequest request) {
				String requestPath = request.getServletPath();
				if(!restful(requestPath)) {
					return false;
				}
				return "XMLHttpRequest".equals(request.getHeader("X-Requested-With")) || (request.getHeader("Accept") != null && request.getHeader("Accept").contains("application/json"));
			}
		});
	}
	
	public boolean restful(String requestPath) {
		List<String> execludeUrls = new ArrayList<String>(Arrays.asList("/app","/wxgzh"));
		for (String url : execludeUrls) {
			if(requestPath.contains(url)) {
				return false;
			}
		}
		return true;
	}

	@Override
	public void configure(WebSecurity web) throws Exception {
		web.ignoring().antMatchers("/api/**","/user/**","/admin/**","/auth/**");
	}

	
	@Bean
	public PasswordEncoder passwordEncoder() {
		return new PasswordEncoder() {

			@Override
			public boolean matches(CharSequence rawPassword, String encodedPassword) {
				return encodedPassword.equals(DigestUtils.md5Hex((String) rawPassword));
			}

			@Override
			public String encode(CharSequence rawPassword) {
				return DigestUtils.md5Hex((String) rawPassword);
			}
		};
	}

}
